#include "drv_uart.h"

/**
* @Description:
* @param none.
* @return none
*/
void uart_gpio_cfg(const uart_gpio *pgpio)
{
    if (pgpio == NULL)
        return;
	
	GPIO_InitTypeDef gpio_init;
    gpio_init.Pin = pgpio->pin;
	gpio_init.Mode = GPIO_MODE_AF_PP;
	gpio_init.Pull = GPIO_PULLUP;
	gpio_init.Speed = GPIO_SPEED_FAST;
	gpio_init.Alternate = pgpio->pinaf;
	HAL_GPIO_Init(pgpio->gpio, &gpio_init);	
}


/**
* @Description:
* @param none.
* @return none
*/
void uart_cfg(const uart_para_t *puart)
{
    if (puart == NULL)
        return;
	UART_HandleTypeDef uartinit;
	
	uartinit.Instance		= puart->uartx;
	uartinit.Init.BaudRate 	= puart->baudrate;
	uartinit.Init.WordLength = puart->wordlength;
	uartinit.Init.StopBits 	= puart->stopbits;
	uartinit.Init.Parity 	= puart->parity;
	uartinit.Init.Mode 		= puart->mode;
	uartinit.Init.HwFlowCtl = puart->hwflowctl;
	uartinit.Init.OverSampling = puart->oversampling;
	HAL_UART_Init(&uartinit);
	__HAL_UART_ENABLE_IT(&uartinit, UART_IT_IDLE);
    SET_BIT(puart->uartx->CR3, USART_CR3_DMAT);
    SET_BIT(puart->uartx->CR3, USART_CR3_DMAR);
}

void tx_dma_cfg(const uart_dma *pdma)
{
    DMA_HandleTypeDef dma_init;

	dma_init.Instance = pdma->dma_stream;
	dma_init.Init.Channel = pdma->channel;
    dma_init.Init.Direction = DMA_MEMORY_TO_PERIPH;
    dma_init.Init.PeriphInc	= DMA_PINC_DISABLE;
    dma_init.Init.MemInc 	= DMA_MINC_ENABLE;
    dma_init.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    dma_init.Init.MemDataAlignment 	= DMA_MDATAALIGN_BYTE;
    dma_init.Init.Mode 				= DMA_NORMAL;
    dma_init.Init.Priority			= pdma->priority;
	dma_init.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
	dma_init.Instance->PAR = (uint32_t)&(pdma->uartx->DR);
	dma_init.Instance->M0AR = (uint32_t)pdma->memoryaddr;
    dma_init.Instance->NDTR = pdma->bufsize;
	HAL_DMA_Init(&dma_init);

	__HAL_DMA_ENABLE_IT(&dma_init, DMA_IT_TC | DMA_IT_TE);
	__HAL_DMA_CLEAR_FLAG(&dma_init, DMA_IT_TC);
}


void rx_dma_cfg(const uart_dma *pdma)
{
    DMA_HandleTypeDef dma_init;

	dma_init.Instance = pdma->dma_stream;
	dma_init.Init.Channel = pdma->channel;
    dma_init.Init.Direction = DMA_PERIPH_TO_MEMORY;
    dma_init.Init.PeriphInc	= DMA_PINC_DISABLE;
    dma_init.Init.MemInc 	= DMA_MINC_ENABLE;
    dma_init.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    dma_init.Init.MemDataAlignment 	= DMA_MDATAALIGN_BYTE;
    dma_init.Init.Mode 				= DMA_CIRCULAR;
    dma_init.Init.Priority			= pdma->priority;
	dma_init.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
	dma_init.Instance->PAR = (uint32_t)&(pdma->uartx->DR);
	dma_init.Instance->M0AR = (uint32_t)pdma->memoryaddr;
    dma_init.Instance->NDTR = pdma->bufsize;
	HAL_DMA_Init(&dma_init);

	__HAL_DMA_ENABLE_IT(&dma_init, DMA_IT_TC | DMA_IT_TE | DMA_IT_HT);
	__HAL_DMA_CLEAR_FLAG(&dma_init, DMA_IT_TC);
	__HAL_DMA_CLEAR_FLAG(&dma_init, DMA_IT_HT);
	__HAL_DMA_ENABLE(&dma_init);
}

/**
* @Description:
* @param none.
* @return none
*/
void nvic_cfg(void)
{
	HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
	HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
	
	HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 2);
	HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
	
	HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 3);
	HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}

void clock_open(void)
{
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_USART1_CLK_ENABLE();
	__HAL_RCC_DMA2_CLK_ENABLE();
}

extern void uart_dmatx_done_isr(unsigned char index);
extern void uart_dmarx_done_isr(unsigned char index);
extern void uart_dmarx_half_done_isr(unsigned char index);
extern void uart_idle_isr(unsigned char index);

void USART1_IRQHandler(void)
{
	uint32_t tmp;
	tmp = USART1->SR & USART_SR_IDLE;
	if (tmp == USART_SR_IDLE)
	{
		uart_idle_isr(0);
		tmp = USART1->SR;
		tmp = USART1->DR;
		UNUSED(tmp);
	}
}

void DMA2_Stream7_IRQHandler(void)
{
	if ((DMA2->HISR & DMA_FLAG_TCIF3_7) == DMA_FLAG_TCIF3_7)
	{
		uart_dmatx_done_isr(0);
		DMA2->LIFCR |= DMA_HIFCR_CTCIF7;
        DMA2_Stream7->CR |=  DMA_SxCR_EN;
	}
}

void DMA2_Stream2_IRQHandler(void)
{
	if ((DMA2->LISR & DMA_FLAG_TCIF2_6) == DMA_FLAG_TCIF2_6)
	{
		uart_dmarx_done_isr(0);
		DMA2->LIFCR |= DMA_LIFCR_CTCIF2;
	}
	if ((DMA2->LISR & DMA_FLAG_HTIF2_6) == DMA_FLAG_TCIF2_6)
	{
		uart_dmarx_half_done_isr(0);
		DMA2->LIFCR |= DMA_LIFCR_CHTIF2;
	}
}


